home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-20
/
nrd33.zip
/
NRDUTIL.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1991-05-19
|
17KB
|
550 lines
{$I-}
{$V-}
unit nrdutil;
interface
uses crt, screen, nrdio;
type prompttype = (PAGE1, PAGE2);
const
{ Receiver window screen limits }
REC_WIN_X_TOP = 1;
REC_WIN_Y_TOP = 1;
REC_WIN_X_BOTTOM = 79;
REC_WIN_Y_BOTTOM = 5;
REVISION = '3.3';
var x_pos, y_pos:integer;
prompt_num:prompttype;
procedure sort(var data:sort_array_type; var index:recarraytype;
start, points:integer);
procedure editfield(x,y,fieldlen:integer; number:boolean;
var tabkey, backtabkey:boolean; var val:lstring);
procedure top_window;
procedure bottom_window;
procedure write_prompt(s:string);
procedure cmd_prompt(prompt_num:prompttype);
procedure do_help;
implementation
procedure sort;
(* THIS PROCEDURE IMPLEMENTS 'QUICKSORT' BY C.A.R. HOARE. THIS N*LOG(N) *)
(* ALGORITHM IS A PARTITION EXCHANGE SORT AND IS DOCUMENTED IN THE 7-80 *)
(* ISSUE OF 'MICRO'. *)
TYPE STACKTYPE = RECORD
UPPER:1..MAXREC; (*STORAGE FOR UPPER SEARCH RANGE*)
LOWER:1..MAXREC (* " " LOWER " " *)
END;
VAR P,Q (*CURRENT LOWER & UPPER INDEX BOUNDS TO BE SORTED. DATA[P] IS
USED AS A COMPARISON KEY IN THE SORTING PROCESS. *)
,I (*STARTS AT P & IS INCREMENTED UNTIL DATA[I]>=DATA[P]. *)
,J (*STARTS AT Q & IS DECREMENTED UNTIL DATA[I]<=DATA[P]. *)
,STACKPTR:INTEGER;
STACK:PACKED ARRAY[1..MAXREC] OF STACKTYPE; (*SEARCH RANGE STORAGE.*)
TEMPDATA,VALUE (*DATA[P]*):short_str;
TEMPINDEX:1..MAXREC;
BEGIN
P:=start; Q:=POINTS + start - 1; STACKPTR:=0;
REPEAT
WHILE P < Q DO
BEGIN
VALUE:=DATA[P]; I:=P; J:=Q + 1;
REPEAT
REPEAT J:=J - 1 UNTIL DATA[J]<=VALUE;
REPEAT inc(I) UNTIL DATA[I]>=VALUE;
IF J > I THEN
BEGIN
TEMPDATA:=DATA[I]; TEMPINDEX:=INDEX[I];
DATA[I] :=DATA[J]; INDEX[I] :=INDEX[J];
DATA[J] :=TEMPDATA;INDEX[J] :=TEMPINDEX
END;
UNTIL J <= I;
TEMPINDEX:=INDEX[P];
DATA[P]:=DATA[J]; INDEX[P]:=INDEX[J];
DATA[J]:=VALUE; INDEX[J]:=TEMPINDEX;
inc(STACKPTR);
IF J - P < Q - J
THEN
WITH STACK[STACKPTR] DO
BEGIN LOWER:=J + 1; UPPER:=Q; Q:=J - 1
END
ELSE
WITH STACK[STACKPTR] DO
BEGIN LOWER:=P; UPPER:=J - 1; P:=J + 1
END;
END; (*WHILE*)
write(output,'.');
IF STACKPTR > 0 THEN (*GRAB NEW SEARCH RANGE OFF STACK*)
WITH STACK[STACKPTR] DO BEGIN Q:=UPPER; P:=LOWER END;
STACKPTR:=STACKPTR-1
UNTIL STACKPTR < 0 (*EMPTY STACK*)
END;
procedure editfield;
{ parameters: x,y = cursor position
fieldlen = allowable length for field
number = flag that if true restricts the keys usable
val = return string }
var ptr,i:integer;
ch:char;
errflg,flag,insert_mode:boolean;
oldval:string[255];
procedure show_line(x,y,fieldlen:integer; val:lstring; edit:boolean);
var i:integer;
lf_bracket,rt_bracket:char;
begin { show_line }
gotoxy(x,y + 1);
if edit then { they are editing this line }
begin
lf_bracket:='[';
rt_bracket:=']';
writea(RED,BACKGROUND);
writea(BLACK,FOREGROUND);
end
else
begin
writea(CYAN,BACKGROUND);
writea(BLACK,FOREGROUND);
lf_bracket:=' ';
rt_bracket:=' ';
end;
write(lf_bracket,val);
gotoxy(x + 1 + fieldlen,y + 1);
write(rt_bracket);
end; { show_line }
procedure blankfill(fieldlen:integer; var val:lstring);
begin
while length(val) < fieldlen do val:=concat(val,' ');
end;
procedure get_normal;
{ fetch normal character and display it. Handle field overflow and
insert_mode }
var i:integer;
s:string[1];
begin
if ptr < fieldlen
then
begin
if ((number) and (ch in ['0'..'9',' ','.']))
or ((ptr = 0) and (ch = '-')) or not number then
begin { all's well }
if not insert_mode then
begin
write(ch); { echo character to screen }
ptr:=ptr + 1;
val[ptr]:=ch
end
else { handle insert mode }
begin
inc(ptr);
for i:=fieldlen downto ptr do val[i]:=val[i - 1];
val[ptr]:=ch;
for i:=ptr to fieldlen do write(val[i]);
gotoxy(x + ptr + 1,y + 1);
end
end
end
end; { get_normal }
procedure do_backspace;
begin
if ptr > 0 then { it's ok to backspace }
begin
ptr:=ptr - 1;
gotoxy(x + ptr + 1,y + 1)
end
end;
procedure do_forwardspace;
begin
if ptr < fieldlen then { its ok to forward space }
begin
inc(ptr);
gotoxy(x + ptr + 1,y + 1)
end
end;
procedure do_del;
var i:integer;
begin
for i:=ptr + 1 to fieldlen - 1 do val[i]:=val[i + 1];
val[fieldlen]:=' ';
for i:=ptr + 1 to fieldlen do write(val[i]);
gotoxy(x + ptr + 1,y + 1);
end;
procedure do_rub;
var i:integer;
begin
if ptr > 0 then ptr:=ptr - 1;
gotoxy(x + ptr + 1,y + 1);
do_del;
end;
procedure toggle_insert;
begin
insert_mode:=not insert_mode;
end;
procedure do_home;
begin
ptr:=0;
gotoxy(x + ptr + 1,y + 1)
end;
procedure do_end;
begin
ptr:=fieldlen;
while (ptr > 0) and (val[ptr] = ' ') do
ptr:=ptr - 1;
gotoxy(x + ptr + 1,y + 1)
end;
procedure do_tab;
begin
tabkey:=TRUE;
ch:=chr(13);
end;
procedure do_backtab;
begin
backtabkey:=TRUE;
ch:=chr(13);
end;
begin { editfield }
insert_mode:=FALSE;
tabkey:=FALSE;
backtabkey:=FALSE;
if number and (val = '-0.00') then val:='0.00';
oldval:=val; { save copy in case they abort }
if length(val) > fieldlen then val:=copy(val,1,fieldlen);
blankfill(fieldlen,val);
ptr:=0;
show_line(x,y,fieldlen,val,TRUE);
gotoxy(x + 1,y + 1);
repeat
ch:=fetch;
if (ch <> chr(13)) and (ord(ch) >= ord(' ')) then get_normal
else if ch = keyinfo.bskey then do_backspace
else if ch = keyinfo.fskey then do_forwardspace
else if ch = keyinfo.delkey then do_del
else if ch = keyinfo.rubkey then do_rub
else if ch = keyinfo.inskey then toggle_insert
else if ch = keyinfo.homekey then do_home
else if ch = keyinfo.endkey then do_end
else if ch = keyinfo.tabkey then do_tab
else if ch = keyinfo.backtabkey then do_backtab
until (ch = chr(13)) or (ch = keyinfo.esckey);
if number then { strip off trailing blanks }
begin
ptr:=length(val);
flag:=TRUE;
while (ptr > 0) and flag do
begin
flag:=val[ptr] = ' ';
if flag then delete(val,ptr,1);
ptr:=ptr - 1;
end;
end;
show_line(x,y,fieldlen,val,FALSE);
end; { editfield }
procedure top_window;
begin
window(REC_WIN_X_TOP,REC_WIN_Y_TOP,REC_WIN_X_BOTTOM+1,REC_WIN_Y_BOTTOM);
end;
procedure bottom_window;
begin
window(1,REC_WIN_Y_BOTTOM + 1, 80,24);
gotoxy(x_pos,y_pos);
end;
procedure write_prompt;
{ write green prompt at top of top window; leave with light gray foreground
and in top window }
begin
top_window;
writea(GREEN,FOREGROUND);
writea(BLACK,BACKGROUND);
gotoxy(1,1);
clreol;
write(output,s);
writea(LIGHTGRAY,FOREGROUND);
end;
procedure cmd_prompt;
const T0 = 'NRD'+REVISION;
T1 = ': L(og, C(onfirm, S(ort, E(dit, T(une, P(age, H(elp, ';
T2 = 'Q(uit [/]';
T3 = 's-meteR, ';
begin
case prompt_num of
PAGE1: if has_map then write_prompt(T0+T1+'K(iwa, '+T2)
else if radio_type = 525 then write_prompt(T0+T1+T2)
else write_prompt(T0+T1+T3+T2);
PAGE2:write_prompt(T0+
': D(elete, uN(delete, M(ark, U(nmark, J(ournal, A(lternate, W(rite [/]');
end;
end;
procedure do_help;
var ch:char;
procedure help_commands;
var ch:char;
begin
write_prompt('Help -- Receiver display <Hit any key to return>');
window(1,REC_WIN_Y_BOTTOM + 1, 80,25);
home;
writeln(output,
'Commands are designed to be easy to learn and use. All commands are');
writeln(output,
'activated with a single key and are spelled out on the command line. For');
writeln(output,
'example, to log a station, hit "L" (shows up as "L(og" on prompt).');
writeln(output);
writeln(output,'Command Summary:');
writeln(output);
writeln(output,
'/: Toggles command menu (commands from both menus are always active)');
writeln(output,
'L: Log (creates new entry in log, receiver contents automatically included)'
);
writeln(output,
'C: Confirm (updates time, date, receiver contents for highlighted entry)');
writeln(output,
'S: Sort data base with 2 sort keys');
writeln(output,
'E: Edit field where cursor is located. Hit ENTER or a TAB key when done');
writeln(output,
'T: Tune receiver to highlighted entry. Updates all receiver parameters');
writeln(output,
'P: Page right (the contents for an entry span 3 pages, faster than tabs)');
writeln(output,'D: Deletes a log entry');
writeln(output,
'N: uNdeletes a log entry (logging new stations reuses deleted space)');
writeln(output,
'M: Mark line(s) for writing or moving to other datalogs (see Journal)');
writeln(output,'U: Unmark lines');
writeln(output,'A: Alternates between Active and Inactive Logs');
writeln(output,'W: Write entry from Inactive Log to Active Log');
write(output,'Q: Quits the program');
ch:=fetch;
home;
end;
procedure help_more;
var ch:char;
begin
write_prompt('Help -- More Commands <Hit any key to return>');
bottom_window;
home;
writeln(output,
'J: Journal: allows you to select other data logs and do things with them.');
writeln(output,
' I keep multiple logs -- a music log for stations that play');
writeln(output,
' interesting music and target logs for areas I''m trying to get.');
writeln(output,
' Target logs allow you to scan what''s there VERY quickly.');
writeln(output,
' The Write command allows marked areas to be moved from'
);
writeln(output,
' one database to another; like when you find one of those targets!'
);
writeln(output,
' Move is like a write but deletes the marked entry. Print writes');
writeln(output,
' the selected database to your printer. Import will copy data');
writeln(output,
' from Tom Sundstrom''s English Language SW Broadcast Schedules to');
writeln(output,
' this program format. You can order these from Tom (609) 859-2447.'
);
if has_map then
begin
writeln(output,
'K: KIWA (this only applies if you have a KIWA Map unit) "K" toggles KIWA');
writeln(output,
' mode. When enabled, the receiver is placed in AM and the radio');
writeln(output,
' is detuned a couple of Khz for good fidelity. Stations logged or'
);
writeln(output,
' confirmed will be rounded to the nearest 5 Khz. Disabling puts');
writeln(output,
' the radio in ECS mode with the appropriate sideband selected based'
);
writeln(output,
' on the offset. The MAP unit provides synchronous detection for a'
);
writeln(output,
' 525 and was described in Guy Atkin''s 9/90 NASWA article p.18. To'
);
writeln(output,
' tell the program you have a MAP, delete the config.dat file and');
write(output,
' rerun program.');
end;
if radio_type = 535 then
begin
writeln(output,
'R: s-meteR: Toggles mode of periodically updating computer S-Meter display.'
);
writeln(output,
' Unfortunately, reading the S-Meter can cause annoying synthesizer'
);
writeln(output,
' re-locking noise in LSB, USB, CW, and RTTY modes. Use this mode');
writeln(output,
' to disable this when it bothers you');
end;
ch:=fetch;
end;
procedure help_receiver;
var ch:char;
begin
write_prompt('Help -- Receiver display <Hit any key to return>');
bottom_window;
home;
gotoxy(1,3);
writeln(output,
'The box labled "NRD',radio_type
,' Status" contains the last sampled receiver status.'
);
writeln(output,
'Mostly, this is self-explanatory. BW = Bandwidth, Freq is the receiver'
);
writeln(output,
'frequency. If the attenuator is active, you will see "ATT" at the right'
);
writeln(output,
'of the screen. If you said you had a KIWA Map unit and it is active, you'
);
writeln(output,
'will see a "K" at the far right of the status box. The KIWA features are'
);
writeln(output,
'described in the commands section. If you don''t have one, don''t worry'
);
writeln(output,
'about this. Normally, the status is displayed in CYAN unless something'
);
writeln(output,
'has changed since the last sample. Changes are displayed in RED. To cause'
);
writeln(output,
'the receiver status to be sampled, hit any non-command key (like space).'
);
writeln(output,
'This approach to updating the display was chosen deliberately to keep the'
);
write(output,
'radio "unlocked" so you can punch up commands on the radio.');
ch:=fetch;
end;
procedure help_other;
var ch:char;
begin
write_prompt('Help -- Receiver display <Hit any key to return>');
bottom_window;
home;
gotoxy(1,3);
writeln(output,
'There are other useful keys not covered in the command section. First off,'
);
writeln(output,
'all the normal cursor commands work including tabs. HOME takes you to the'
);
writeln(output,
'top of the display log, END takes you to the bottom. Control-PAGE keys'
);
writeln(output,
'work like PAGE keys, only 10 pages at a time. "+" and "-" keys bump the'
);
writeln(output,
'frequency up or down 5 Khz. If you are in USB or LSB mode, the program'
);
writeln(output,
'assumes you are using ECS detection and tunes off 1 Khz for a fraction of'
);
writeln(output,
'a second before tuning in the correct frequency. This feature was added to'
);
writeln(output,
'hear the heterodyne of weak stations you might miss while rapidly scanning.'
);
writeln(output,
'The "<" and ">" keys (or the "," and "." keys so no shifting is needed)'
);
writeln(output,
'decrement or increment the receiver mode. Similarly, the "[" and "]" keys'
);
writeln(output,
'bump the receiver bandwidth selection. "*" will find the closest');
writeln(output,
'log entry for the currently tuned frequency');
writeln(output);
writeln(output,
'The offset from GMT to your computer''s time is stored in the "CONFIG.DAT"'
);
writeln(output,
'file. If this is wrong, delete CONFIG.DAT and the program will prompt you'
);
write(output,
'for the information to correct.');
ch:=fetch;
end;
begin
repeat
bottom_window;
home;
gotoxy(1,8);
writeln(output,
'Type letter for command. For example, to learn more about the receiver');
writeln(output,
'display, type "r". Type "q" to return from the help facility.');
write_prompt(
'Help: R(eceiver display, C(ommands, M(ore commands, O(ther, Q(uit');
ch:=upcase(fetch);
case ch of
'R': help_receiver;
'C': help_commands;
'M': help_more;
'O': help_other;
end;
until ch = 'Q';
cmd_prompt(prompt_num);
bottom_window;
end;
begin
end.